package com.junyidao.game.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.junyidao.game.Exception.BusinessException;
import com.junyidao.game.mapper.TWechatPayOrderMapper;
import com.junyidao.game.pay.AlipayConstant;
import com.junyidao.game.constant.PayType;
import com.junyidao.game.core.LoginInfo;
import com.junyidao.game.mapper.TAccountDetailMapper;
import com.junyidao.game.mapper.TAccountMapper;
import com.junyidao.game.mapper.TAlipayOrderMapper;
import com.junyidao.game.pay.PayConstant;
import com.junyidao.game.pay.WechatPayAccount;
import com.junyidao.game.pojo.*;
import com.junyidao.game.util.CommonUtil;
import com.junyidao.game.util.NumUtils;
import com.junyidao.game.util.PayOrderNogGenerator;
import com.junyidao.game.util.XMLUtil;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zzh on 2016/9/26.
 * 文件描述 ：账号充值
 */
@Service
@Transactional
public class AccountChargeService {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AccountChargeService.class);

    @Autowired
    private UserService userService;

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private SequenceService sequenceService;

    @Autowired
    private TAlipayOrderMapper alipayOrderMapper;

    @Autowired
    private TAccountDetailMapper accountDetailMapper;

    @Autowired
    private TAccountMapper accountMapper;

    @Autowired
    private TWechatPayOrderMapper wechatPayOrderMapper;

    @Autowired
    private WechatPayService wechatPayService;

    /**
     * 账号充值
     *
     * @param accountName
     * @param amount
     * @param payType
     * @return
     */
    public Map<String, String> accountCharge(String accountName, Integer amount, Integer payType) {
        Map<String, String> map = new HashMap<>();
        SysUser user = userService.getUser(accountName);
        if (user == null) {
            BusinessException.throwException(1, "充值账号不存在");
        }
        String qrCodeUrl = "";
        String outTradeNo = "";
        if (payType == PayType.PAY_TYPE_ALIPAY) {
            TAlipayOrder alipayOrder = addAlipayOrder(amount, user.getUid());
            addAccountDetail(amount, user.getUid(), alipayOrder.getAlipayOrderId(), payType);
            outTradeNo = alipayOrder.getOutTradeNo();
            qrCodeUrl = alipayService.getAlipayQRCode(amount, outTradeNo, alipayOrder.getSubject(), AlipayConstant.PAY_TIME_OUT);

        } else if (payType == PayType.PAY_TYPE_WECHAT) {
            TWechatPayOrder order = addWechatPayOrder(amount, user.getUid());
            addAccountDetail(amount, user.getUid(), order.getWechatPayOrderId(), payType);
            outTradeNo = order.getWechatPayOrderId().toString();
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String ip = "127.0.0.1";
            try {
                ip = CommonUtil.getIpAddress(request);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String payNotifyUrl = "/payNotify/wechatPay/" + order.getWechatPayOrderId();
            Map<String, String> ret = wechatPayService.unifiedOrder(WechatPayAccount.APPID, WechatPayAccount.MCH_ID, WechatPayAccount.MCH_KEY,
                    "测试", order.getOutTradeNo(), amount, ip, payNotifyUrl, order.getOutTradeNo());
            logger.info("统一下单返回结果：", ret);
            if (ret == null) {
                BusinessException.throwException(1, "系统繁忙");
            }
            qrCodeUrl = ret.get("code_url");
        }
        map.put("qrCodeUrl", qrCodeUrl);
        map.put("outTradeNo", outTradeNo);
        return map;
    }

    /**
     * 新增支付宝支付订单
     * @param amount
     * @param uid
     * @return
     */
    public TAlipayOrder addAlipayOrder(Integer amount, Integer uid) {
        TAlipayOrder alipayOrder = new TAlipayOrder();
        Integer id = sequenceService.getNextSequence("ALIPAY_ORDER_ID");
        String outTraddNo = PayOrderNogGenerator.generate(LoginInfo.getUser().getUid(), PayType.PAY_TYPE_ALIPAY);
        alipayOrder.setAlipayOrderId(id);
        alipayOrder.setOutTradeNo(outTraddNo);
        alipayOrder.setTotalAmount(amount);
        alipayOrder.setSubject("君易道游戏充值");
        alipayOrder.setUid(uid);
        alipayOrder.setTradeStatus(AlipayConstant.WAIT_BUYER_PAY);
        alipayOrder.setCreateTime(new Date());
        alipayOrderMapper.insert(alipayOrder);
        return alipayOrder;
    }

    /**
     * 微信支付订单
     *
     * @param amount
     * @param uid
     * @return
     */
    public TWechatPayOrder addWechatPayOrder(Integer amount, Integer uid) {
        TWechatPayOrder order = new TWechatPayOrder();
        Integer id = sequenceService.getNextSequence("WECHAT_PAY_ORDER_ID");
        String outTraddNo = PayOrderNogGenerator.generate(LoginInfo.getUser().getUid(), PayType.PAY_TYPE_WECHAT);
        order.setWechatPayOrderId(id);
        order.setUid(uid);
        order.setTradeStatus(PayConstant.CREATE_ORDER);
        order.setCreateTime(new Date());
        order.setOutTradeNo(outTraddNo);
        order.setBody("君易道游戏充值");
        order.setDetail("君易道游戏充值");
        order.setTotalAmount(amount);
        wechatPayOrderMapper.insert(order);
        return order;
    }

    /**
     * 充值详情
     *
     * @param amount
     * @param uid
     * @param orderId
     * @return
     */
    public TAccountDetail addAccountDetail(Integer amount, Integer uid, Integer orderId, Integer payType) {
        Integer id = sequenceService.getNextSequence("ACCOUNT_DETAIL");
        TAccountDetail accountDetail = new TAccountDetail();
        accountDetail.setAccId(id);
        accountDetail.setUid(uid);
        accountDetail.setAccUid(LoginInfo.getUser().getUid());
        accountDetail.setAccMoney(amount);
        accountDetail.setAccTime(new Date());
        accountDetail.setAccChannel(String.valueOf(payType));
        accountDetail.setOrderId(orderId);
        accountDetail.setOrderStatus(PayConstant.CREATE_ORDER);
        accountDetailMapper.insert(accountDetail);
        return accountDetail;
    }

    /**
     * 查询充值状态
     * @param payType 支付类型 1 支付宝支付  2 微信支付
     * @param outTradeNo
     * @return
     */
    public String queryPayStatus(Integer payType, String outTradeNo) {
        String tradeStatus = "FAIL";
        if (payType == PayType.PAY_TYPE_ALIPAY) {
            AlipayTradeQueryResponse response = alipayService.queryPayStatus(outTradeNo);
            tradeStatus = response.getTradeStatus();
            if (tradeStatus.equals(AlipayConstant.TRADE_SUCCESS) || tradeStatus.equals(AlipayConstant.TRADE_FINISHED)) {
                updateAlipayOrder(response);
                tradeStatus = "SUCCESS";
            }
        } else if (payType == PayType.PAY_TYPE_WECHAT) {
            TWechatPayOrder payOrder = new TWechatPayOrder();
            payOrder.setWechatPayOrderId(Integer.valueOf(outTradeNo));
            TWechatPayOrder order = wechatPayOrderMapper.selectOne(payOrder);
            Map<String, String> retMap = wechatPayService.queryOrder(WechatPayAccount.APPID, WechatPayAccount.MCH_ID, order.getOutTradeNo(), WechatPayAccount.MCH_KEY);
            tradeStatus = wechatPayResultDeal(retMap, Integer.valueOf(outTradeNo));
//            if(order.getTradeStatus().equals(PayConstant.PAY_SUCCESS.toString())){
//                tradeStatus = "SUCCESS";
//            }
        }
        return tradeStatus;
    }

    /**
     * 更新支付宝支付订单
     * @param response
     */
    public void updateAlipayOrder(AlipayTradeQueryResponse response) {
        TAlipayOrder alipayOrder = new TAlipayOrder();
        alipayOrder.setOutTradeNo(response.getOutTradeNo());
        TAlipayOrder order = alipayOrderMapper.selectOne(alipayOrder);
        order.setTradeStatus(response.getTradeStatus());
        order.setCode(response.getCode());
        order.setMsg(response.getMsg());
        order.setSubCode(response.getSubCode());
        order.setSubMsg(response.getSubMsg());
        order.setTradeNo(response.getTradeNo());
        order.setBuyerLogonId(response.getBuyerLogonId());
        order.setBuyerUserId(response.getBuyerUserId());
        order.setReceiptAmount(NumUtils.multiply(Double.valueOf(response.getReceiptAmount()), 100).intValue());
        order.setSendPayDate(response.getSendPayDate());
        order.setFundBillList(JSONUtils.toJSONString(response.getFundBillList()));
        order.setUpdateTime(new Date());
        alipayOrderMapper.updateAlipayOrder(order);
        updateAccountDetail(alipayOrder.getAlipayOrderId(), response.getBuyerLogonId(), String.valueOf(PayType.PAY_TYPE_ALIPAY));

    }

    /**
     * 更新充值详情
     *
     * @param orderId
     * @param accSource
     */
    public void updateAccountDetail(Integer orderId, String accSource,String payType) {
        TAccountDetail accountDetail = new TAccountDetail();
        accountDetail.setOrderId(orderId);
        accountDetail.setAccChannel(payType);
        TAccountDetail detail = accountDetailMapper.selectOne(accountDetail);
        detail.setOrderStatus(PayConstant.PAY_SUCCESS);
        detail.setAccSource(accSource);
        accountDetailMapper.updateTAccountDetail(detail);
        updateAccount(detail.getUid(), detail.getAccMoney());
    }

    /**
     * 更新账户金额
     * @param uid
     * @param amount
     */
    public void updateAccount(Integer uid, Integer amount) {
        TAccount account = new TAccount();
        account.setUid(uid);
        TAccount acc = accountMapper.selectOne(account);
        if (acc == null) {
            acc = new TAccount();
            acc.setUid(uid);
            acc.setAccount(amount);
            acc.setLastUpdateTime(new Date());
            accountMapper.insert(acc);
        } else {
            acc.setAccount(amount+acc.getAccount());
            acc.setLastUpdateTime(new Date());
            accountMapper.updataTAccount(acc);
        }
    }

    /**
     * 更新微信支付订单(支付成功)
     *
     * @param map
     * @param orderId
     */
    public void updateWechatPayOrder(Map<String, String> map, Integer orderId) {
        TWechatPayOrder payOrder = new TWechatPayOrder();
        payOrder.setWechatPayOrderId(orderId);
        String transaction_id = map.get("transaction_id");
        String time_end = map.get("time_end");
        String openid = map.get("openid");
        payOrder.setTransactionId(transaction_id);
        payOrder.setOpenid(openid);
        payOrder.setTimeEnd(time_end);
        payOrder.setUpdateTime(new Date());
        payOrder.setTradeStatus(PayConstant.PAY_SUCCESS);
        wechatPayOrderMapper.updateWechatPayOrder(payOrder);
        updateAccountDetail(orderId, openid, String.valueOf(PayType.PAY_TYPE_WECHAT));
    }

    public String wechatPayResultDeal(Map<String, String> map, Integer orderId) {
        if (map == null) {
            logger.info("错误原因:订单查询失败");
            BusinessException.throwException(1, "系统繁忙");
        }
        String return_code = map.get("return_code");
        if (return_code.equals("FAIL")) {
            logger.info("错误原因:" + map.get("return_msg"));
            BusinessException.throwException(1, "系统繁忙");
        }
        String result_code = map.get("result_code");
        if (result_code.equals("FAIL")) {
            logger.info("错误原因:" + map.get("err_code_des"));
            BusinessException.throwException(1, "系统繁忙");
        }
        String sign = map.get("sign");
        String sign2 = wechatPayService.wechatSignature(map, WechatPayAccount.MCH_KEY);
        if (!sign.equals(sign2)) {
            logger.info("错误原因:接受通知签名错误");
            BusinessException.throwException(1, "系统繁忙");
        }
        String tradeState = map.get("trade_state");
        if (!tradeState.equals("SUCCESS")) {
            logger.info("错误原因:用户未支付");
            BusinessException.throwException(1, "用户未支付");
        }
        updateWechatPayOrder(map, orderId);
        return "SUCCESS";
    }
}
